package com.ai.imagetext.service;

import com.ai.imagetext.entity.GeneratedImage;
import com.ai.imagetext.entity.Image;
import com.ai.imagetext.repository.GeneratedImageRepository;
import com.ai.imagetext.repository.ImageRepository;
import com.ai.imagetext.service.AIService.ImageGenerationResult;
import com.ai.imagetext.util.FileUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.awt.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
@RequiredArgsConstructor
public class ImageGenerationService {
    
    private final AIService aiService;
    private final ImageRepository imageRepository;
    private final GeneratedImageRepository generatedImageRepository;
    private final OperationLogService operationLogService;
    private final FileUploadService fileUploadService;
    private final AIRecognitionService aiRecognitionService;
    private final RestTemplate restTemplate = new RestTemplate();
    
    /**
     * 为图片生成相似图片
     */
    @Transactional
    public GeneratedImage generateSimilarImages(Long originalImageId, int count, String style, String customPrompt) {
        log.info("Generating similar images for image: {}, count: {}, style: {}", originalImageId, count, style);
        
        Image originalImage = imageRepository.findByIdAndIsDeletedFalse(originalImageId)
                .orElseThrow(() -> new IllegalArgumentException("原始图片不存在或已删除"));
        
        // 创建生成记录
        GeneratedImage generatedImageRecord = new GeneratedImage();
        generatedImageRecord.setOriginalImage(originalImage);
        generatedImageRecord.setGenerationPrompt(customPrompt);
        generatedImageRecord.setGenerationParams(String.format("{\"count\":%d,\"style\":\"%s\"}", count, style));
        generatedImageRecord.setAiGenerationStatus(GeneratedImage.AIGenerationStatus.PENDING);
        generatedImageRecord.setIsDeleted(false);
        
        GeneratedImage savedRecord = generatedImageRepository.save(generatedImageRecord);
        
        // 异步生成图片
        generateImagesAsync(savedRecord, count, style, customPrompt);
        
        return savedRecord;
    }
    
    /**
     * 异步生成图片
     */
    @Async("aiTaskExecutor")
    @Transactional
    public void generateImagesAsync(GeneratedImage generatedImageRecord, int count, String style, String customPrompt) {
        log.info("Starting async image generation for record: {}", generatedImageRecord.getId());
        
        try {
            // 调用AI服务生成图片
            ImageGenerationResult result = aiService.generateSimilarImages(
                    generatedImageRecord.getOriginalImage().getFileUrl(),
                    count,
                    style,
                    customPrompt
            );
            
            if (result.isSuccess() && !result.getGeneratedImageUrls().isEmpty()) {
                // 下载并保存生成的图片
                List<Image> savedImages = downloadAndSaveGeneratedImages(result.getGeneratedImageUrls(), generatedImageRecord);
                
                if (!savedImages.isEmpty()) {
                    // 更新生成记录
                    Image firstGeneratedImage = savedImages.get(0);
                    generatedImageRecord.setGeneratedImage(firstGeneratedImage);
                    generatedImageRecord.setAiGenerationStatus(GeneratedImage.AIGenerationStatus.SUCCESS);
                    generatedImageRecord.setSimilarityScore(BigDecimal.valueOf(0.85)); // 默认相似度
                    
                    log.info("Image generation completed successfully for record: {}, generated {} images", 
                             generatedImageRecord.getId(), savedImages.size());
                } else {
                    // 下载失败
                    generatedImageRecord.setAiGenerationStatus(GeneratedImage.AIGenerationStatus.FAILED);
                    log.warn("Failed to download generated images for record: {}", generatedImageRecord.getId());
                }
            } else {
                // AI生成失败
                generatedImageRecord.setAiGenerationStatus(GeneratedImage.AIGenerationStatus.FAILED);
                log.warn("AI image generation failed for record: {}, error: {}", 
                         generatedImageRecord.getId(), result.getErrorMessage());
            }
            
            generatedImageRepository.save(generatedImageRecord);

            /**
             * 创建用户操作日志数据
             */
            long generatedId = generatedImageRepository.findLatest().get().getId();
            operationLogService.recordImageToImageOperation(generatedImageRecord.getUserId(),
                    generatedImageRecord.getOriginalImage().getId(),generatedId);

        } catch (Exception e) {
            log.error("Unexpected error during image generation for record: {}", generatedImageRecord.getId(), e);
            generatedImageRecord.setAiGenerationStatus(GeneratedImage.AIGenerationStatus.FAILED);
            generatedImageRepository.save(generatedImageRecord);
        }
    }
    
    /**
     * 下载并保存生成的图片
     */
    private List<Image> downloadAndSaveGeneratedImages(List<String> imageUrls, GeneratedImage generatedImageRecord) {
        List<Image> savedImages = new ArrayList<>();
        
        for (int i = 0; i < imageUrls.size(); i++) {
            try {
                String imageUrl = imageUrls.get(i);
                log.info("Downloading generated image {} from URL: {}", i + 1, imageUrl);
                
                // 下载图片
                byte[] imageData = restTemplate.getForObject(imageUrl, byte[].class);
                if (imageData == null || imageData.length == 0) {
                    log.warn("Downloaded image data is empty for URL: {}", imageUrl);
                    continue;
                }
                
                // 生成文件信息
                String originalName = String.format("generated_%d_%d.jpg", generatedImageRecord.getId(), i + 1);
                String uniqueFilename = generateUniqueFilename(originalName);
                String datePath = generateDatePath();
                String relativePath = datePath + "/" + uniqueFilename;
                String fullPath = "./uploads/" + relativePath;
                
                // 创建目录并保存文件
                FileUtils.createDirectoryIfNotExists("./uploads/" + datePath);
                java.nio.file.Files.write(java.nio.file.Paths.get(fullPath), imageData);
                
                // 获取图片尺寸
                Dimension dimensions = getImageDimensions(imageData);
                
                // 创建图片实体
                Image image = new Image();
                image.setName(uniqueFilename);
                image.setOriginalName(originalName);
                image.setFilePath(relativePath);
                image.setFileUrl("http://localhost:8080/uploads/" + relativePath);
                image.setFileSize((long) imageData.length);
                image.setMimeType("image/jpeg");
                image.setWidth((int) dimensions.getWidth());
                image.setHeight((int) dimensions.getHeight());
                image.setDescription("AI生成的相似图片");
                image.setAiRecognitionStatus(Image.AIRecognitionStatus.PENDING);
                image.setUsageCount(0);
                image.setIsDeleted(false);
                
                // 保存到数据库
                Image savedImage = imageRepository.save(image);
                savedImages.add(savedImage);
                
                // 异步执行AI识别
                aiRecognitionService.recognizeAndUpdateImage(savedImage);
                
                log.info("Generated image saved successfully: {}", savedImage.getId());
                
            } catch (Exception e) {
                log.error("Failed to download and save generated image {}: {}", i + 1, e.getMessage());
            }
        }
        
        return savedImages;
    }
    
    /**
     * 批量生成相似图片
     */
    @Async("aiTaskExecutor")
    @Transactional
    public void batchGenerateSimilarImages(List<Long> imageIds, int countPerImage, String style, String customPrompt) {
        log.info("Starting batch image generation for {} images", imageIds.size());
        
        for (Long imageId : imageIds) {
            try {
                generateSimilarImages(imageId, countPerImage, style, customPrompt);
                
                // 添加延迟避免API频率限制
                Thread.sleep(3000);
                
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.warn("Batch image generation interrupted");
                break;
            } catch (Exception e) {
                log.error("Error in batch image generation for image: {}", imageId, e);
            }
        }
        
        log.info("Batch image generation completed");
    }
    
    /**
     * 获取图片的生成记录
     */
    public List<GeneratedImage> getGeneratedImagesForOriginal(Long originalImageId) {
        log.info("Getting generated images for original image: {}", originalImageId);
        return generatedImageRepository.findByOriginalImageIdAndIsDeletedFalse(originalImageId);
    }
    
    /**
     * 获取生成记录详情
     */
    public GeneratedImage getGeneratedImageRecord(Long recordId) {
        log.info("Getting generated image record: {}", recordId);
        return generatedImageRepository.findById(recordId)
                .filter(record -> !record.getIsDeleted())
                .orElseThrow(() -> new IllegalArgumentException("生成记录不存在或已删除"));
    }
    
    /**
     * 删除生成记录
     */
    @Transactional
    public void deleteGeneratedImageRecord(Long recordId) {
        log.info("Deleting generated image record: {}", recordId);
        
        GeneratedImage record = generatedImageRepository.findById(recordId)
                .filter(r -> !r.getIsDeleted())
                .orElseThrow(() -> new IllegalArgumentException("生成记录不存在或已删除"));
        
        // 软删除生成记录
        generatedImageRepository.softDeleteById(recordId);
        
        // 如果有关联的生成图片，也进行软删除
        if (record.getGeneratedImage() != null) {
            imageRepository.softDeleteById(record.getGeneratedImage().getId());
        }
    }
    
    /**
     * 重试失败的图片生成
     */
    @Async("aiTaskExecutor")
    @Transactional
    public void retryFailedGenerations() {
        log.info("Retrying failed image generations");
        
        List<GeneratedImage> failedRecords = generatedImageRepository
                .findByAiGenerationStatusAndIsDeletedFalse(GeneratedImage.AIGenerationStatus.FAILED);
        
        log.info("Found {} failed image generation records to retry", failedRecords.size());
        
        for (GeneratedImage record : failedRecords) {
            try {
                // 解析生成参数
                String params = record.getGenerationParams();
                int count = 3; // 默认值
                String style = "auto"; // 默认值
                
                // 简单解析JSON参数
                if (params != null && params.contains("count")) {
                    try {
                        count = Integer.parseInt(params.replaceAll(".*\"count\":(\\d+).*", "$1"));
                    } catch (Exception e) {
                        log.warn("Failed to parse count from params: {}", params);
                    }
                }
                
                if (params != null && params.contains("style")) {
                    try {
                        style = params.replaceAll(".*\"style\":\"([^\"]+)\".*", "$1");
                    } catch (Exception e) {
                        log.warn("Failed to parse style from params: {}", params);
                    }
                }
                
                // 重新生成
                generateImagesAsync(record, count, style, record.getGenerationPrompt());
                
                // 添加延迟避免API频率限制
                Thread.sleep(5000);
                
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.warn("Retry failed image generations interrupted");
                break;
            } catch (Exception e) {
                log.error("Error retrying image generation for record: {}", record.getId(), e);
            }
        }
        
        log.info("Retry failed image generations completed");
    }
    
    /**
     * 获取图片生成统计信息
     */
    public ImageGenerationStatistics getImageGenerationStatistics() {
        long totalRecords = generatedImageRepository.count();
        long successCount = generatedImageRepository.countByAiGenerationStatusAndIsDeletedFalse(
                GeneratedImage.AIGenerationStatus.SUCCESS);
        long failedCount = generatedImageRepository.countByAiGenerationStatusAndIsDeletedFalse(
                GeneratedImage.AIGenerationStatus.FAILED);
        long pendingCount = generatedImageRepository.countByAiGenerationStatusAndIsDeletedFalse(
                GeneratedImage.AIGenerationStatus.PENDING);
        
        Double avgSimilarityScore = generatedImageRepository.getAverageSimilarityScore();
        
        ImageGenerationStatistics stats = new ImageGenerationStatistics();
        stats.setTotalRecords(totalRecords);
        stats.setSuccessCount(successCount);
        stats.setFailedCount(failedCount);
        stats.setPendingCount(pendingCount);
        stats.setSuccessRate(totalRecords > 0 ? (double) successCount / totalRecords * 100 : 0.0);
        stats.setAverageSimilarityScore(avgSimilarityScore != null ? avgSimilarityScore : 0.0);
        
        return stats;
    }
    
    /**
     * 生成唯一文件名
     */
    private String generateUniqueFilename(String originalFilename) {
        String extension = FileUtils.getFileExtension(originalFilename);
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
        String uuid = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
        return "gen_" + timestamp + "_" + uuid + extension;
    }
    
    /**
     * 生成日期路径
     */
    private String generateDatePath() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
    }
    
    /**
     * 获取图片尺寸
     */
    private Dimension getImageDimensions(byte[] imageData) {
        try {
            java.awt.image.BufferedImage image = javax.imageio.ImageIO.read(new ByteArrayInputStream(imageData));
            if (image != null) {
                return new Dimension(image.getWidth(), image.getHeight());
            }
        } catch (IOException e) {
            log.warn("Failed to read image dimensions", e);
        }
        return new Dimension(1024, 1024); // 默认尺寸
    }
    
    /**
     * 图片生成统计信息
     */
    public static class ImageGenerationStatistics {
        private long totalRecords;
        private long successCount;
        private long failedCount;
        private long pendingCount;
        private double successRate;
        private double averageSimilarityScore;
        
        // Getters and Setters
        public long getTotalRecords() { return totalRecords; }
        public void setTotalRecords(long totalRecords) { this.totalRecords = totalRecords; }
        
        public long getSuccessCount() { return successCount; }
        public void setSuccessCount(long successCount) { this.successCount = successCount; }
        
        public long getFailedCount() { return failedCount; }
        public void setFailedCount(long failedCount) { this.failedCount = failedCount; }
        
        public long getPendingCount() { return pendingCount; }
        public void setPendingCount(long pendingCount) { this.pendingCount = pendingCount; }
        
        public double getSuccessRate() { return successRate; }
        public void setSuccessRate(double successRate) { this.successRate = successRate; }
        
        public double getAverageSimilarityScore() { return averageSimilarityScore; }
        public void setAverageSimilarityScore(double averageSimilarityScore) { this.averageSimilarityScore = averageSimilarityScore; }
    }
}